package top.amot.forceview.drawitem.line

import android.content.Context
import android.graphics.Canvas
import android.graphics.Path
import android.graphics.PointF
import top.amot.forceview.drawitem.AbstractDrawLink
import top.amot.forceview.drawitem.DrawManager
import top.amot.forceview.layout.I_Layout
import top.amot.forceview.model.AbstractLink
import top.amot.forceview.model.AbstractNode
import top.amot.forceview.model.Link
import top.amot.forceview.theme.I_Theme
import top.amot.forceview.util.UiUtil

class DirectLine(context: Context,drawManager: DrawManager) : AbstractDrawLink<Link>(context,drawManager) {

    override fun isType(link: AbstractLink<AbstractNode,AbstractNode>): Boolean {
        return link is Link
    }

    override fun drawLink(
        canvas: Canvas,
        theme: I_Theme,
        layout: I_Layout,
        link: Link,
        isSelectNode: Boolean
    ) {

        val linkPaint = theme.linkPaint
        val linkTextPaint = theme.linkTextPaint
        val startX = link.source.x
        val startY = link.source.y
        val stopX = link.target.x
        val stopY = link.target.y
        var color = theme.linkColor
        if (isSelectNode) {
            color = theme.getColor(link.source.level)
        }
        linkPaint.color = color
        linkTextPaint.color = color
        canvas.drawLine(startX, startY, stopX, stopY, linkPaint)
        val arrowPath = layout.calcLinkPath(link)
        canvas.drawPath(arrowPath, linkPaint)
        val linkTextBaseline = theme.linkTextBaseline
        // draw link text
        val linkText = link.text
        if (linkText != null && linkText.trim { it <= ' ' }.isNotEmpty()) {
            val textPoint = layout.calcLinkText(link)
            canvas.drawText(
                linkText,
                textPoint.x,
                textPoint.y - linkTextBaseline,
                linkTextPaint
            )
        }
    }

    override fun calcLinkPath(link: Link): Path {
        val startPoint=getSourceStartPoint(link.source)
        val stopPoint=getTargetStartPoint(link.target)

        val startX = startPoint.x
        val startY = startPoint.y
        val stopX = stopPoint.x
        val stopY = stopPoint.y

        val radius=link.target.x - stopX
        // draw arrow
        val length = link.length()
        var ratio = (length - radius) / length
        val ax1 = (stopX - startX) * ratio + startX
        val ay1 = (stopY - startY) * ratio + startY
        ratio = (length - radius - UiUtil.dp2px(context, 10.0)) / length
        val ax3 = (stopX - startX) * ratio + startX
        val ay3 = (stopY - startY) * ratio + startY
        ratio = (length - radius - UiUtil.dp2px(context, 12.0)) / length
        val ax24 = (stopX - startX) * ratio + startX
        val ay24 = (stopY - startY) * ratio + startY
        val l = UiUtil.dp2px(context, 5.0).toFloat()
        val dx = (stopY - startY) / length * l
        val dy = (startX - stopX) / length * l
        val ax2 = ax24 - dx
        val ay2 = ay24 - dy
        val ax4 = ax24 + dx
        val ay4 = ay24 + dy
        val arrowPath = Path()
        arrowPath.moveTo(ax1, ay1)
        arrowPath.lineTo(ax2, ay2)
        arrowPath.lineTo(ax3, ay3)
        arrowPath.lineTo(ax4, ay4)
        arrowPath.close()
        return arrowPath

       /*
        val startX = link.source!!.x.toFloat()
        val startY = link.source!!.y.toFloat()
        val stopX = link.target!!.x.toFloat()
        val stopY = link.target!!.y.toFloat()

        // draw arrow
        val length = link.length()
        var ratio = (length - link.target!!.radius) / length
        val ax1 = (stopX - startX) * ratio + startX
        val ay1 = (stopY - startY) * ratio + startY
        ratio = (length - link.target!!.radius - UiUtil.dp2px(context, 10.0)) / length
        val ax3 = (stopX - startX) * ratio + startX
        val ay3 = (stopY - startY) * ratio + startY
        ratio = (length - link.target!!.radius - UiUtil.dp2px(context, 12.0)) / length
        val ax24 = (stopX - startX) * ratio + startX
        val ay24 = (stopY - startY) * ratio + startY
        val l = UiUtil.dp2px(context, 5.0).toFloat()
        val dx = (stopY - startY) / length * l
        val dy = (startX - stopX) / length * l
        val ax2 = ax24 - dx
        val ay2 = ay24 - dy
        val ax4 = ax24 + dx
        val ay4 = ay24 + dy
        val arrowPath = Path()
        arrowPath.moveTo(ax1, ay1)
        arrowPath.lineTo(ax2, ay2)
        arrowPath.lineTo(ax3, ay3)
        arrowPath.lineTo(ax4, ay4)
        arrowPath.close()
        return arrowPath*/
    }

    override fun calcLinkText(link: Link): PointF {
        val startPoint=getSourceStartPoint(link.source)
        val stopPoint=getTargetStartPoint(link.target)

        val startX = startPoint.x
        val startY = startPoint.y
        val stopX = stopPoint.x
        val stopY = stopPoint.y

        // draw arrow
        val length = link.length()
        val textPoint = PointF()
        val radius=link.target.x - stopX
        val ratio = (length - radius - length / 5f) / length
        textPoint.x = (stopX - startX) * ratio + startX
        textPoint.y = (stopY - startY) * ratio + startY
        return textPoint
    }
}